package com.kly.user.task;

import cn.hutool.core.net.NetUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.HttpUtil;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Maps;
import com.google.common.eventbus.AsyncEventBus;
import com.kly.dto.TOrderDto;
import com.kly.enums.ParameterTypeEnum;
import com.kly.service.TOrderService;
import com.kly.user.chatterService.ChatService;
import com.kly.user.db.dao.*;
import com.kly.user.db.entity.*;
import com.kly.user.dto.AddWlmReq;
import com.kly.user.dto.RecommendUserDto;
import com.kly.user.dto.chatter.request.ConversationReq;
import com.kly.user.enums.AppEnum;
import com.kly.user.enums.ConversationType;
import com.kly.user.enums.OnlineStatus;
import com.kly.user.eventbus.ActionEnum;
import com.kly.user.eventbus.Event;
import com.kly.user.service.AsyncSendMsgService;
import com.kly.user.serviceImpl.OtherServiceImpl;
import com.kly.user.serviceImpl.WlmServiceImpl;
import com.kly.user.utils.ServiceUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * flash chat 下发
 */
@Component
public class FlashChatIssueTask {

    private static Log logger = LogFactory.getLog(FlashChatIssueTask.class);

    @NacosValue(value = "${send.flashchat.url:http://localhost:9104/api/im/message/sendMsg}", autoRefreshed = true)
    private String sendFlashchatUrl;

    @NacosValue(value = "${task.job.executor.ip}", autoRefreshed = true)
    private String taskJobExecutor;

    private String localIP = NetUtil.getLocalhostStr();

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserFcConfigDao userFcConfigDao;

    @Autowired
    private UserMsgDao userMsgDao;

    @Resource
    private TOrderService tOrderService;

    @Autowired
    private WlmServiceImpl wlmService;

    @Autowired
    private OtherServiceImpl otherService;

    @Resource
    UserGreetingCommonContentDao userGreetingCommonContentDao;

    @Resource
    UserCommonLogDao commonLogDao;

    @Resource
    AsyncEventBus pushEventBus;

    @Resource
    ChatService chatService;

    @Resource
    private AsyncSendMsgService asyncSendMsgService;

    @Resource
    private IssueFcRecordDao issueFcRecordDao;


    /**
     * 每30秒处理一次 flash chat 下发
     */
//    @Scheduled(fixedDelay = 60000)
    public void execute() {

        if (!taskJobExecutor.contains(localIP)) {
            logger.info("=============NotTaskJobExecutor, currentLocalAddress:{}, onlyExecuteTaskIn:{}", localIP, taskJobExecutor);
            return;
        }

        logger.info("flash chat 下发 start :" + new Date());

        //读取下发配置表
        Map<String, Object> map = new HashMap<>();
        map.put("deleted", 0);
        List<UserFcConfigEntity> userFcConfigEntityList = userFcConfigDao.selectByParams(map);
        if (userFcConfigEntityList != null) {

            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -2);
            Date date = calendar.getTime();
            int count = userDao.getRegisterDateUserCount(String.valueOf(date.getTime()));
            if (count > 0) {
                int pageSize = (count / 100) + 1;
                for (int i = 0; i < pageSize; i++) {
                    List<UserEntity> userEntityList = userDao.getRegisterDateUserLimit(String.valueOf(date.getTime()), i);
                    for (UserEntity userEntity : userEntityList) {
                        for (UserFcConfigEntity userFcConfigEntity : userFcConfigEntityList) {
                            Integer dealResult = dealCondition(userFcConfigEntity, userEntity);
                            if (dealResult != 0) {
                                break;
                            }
                        }
                    }
                    if (userEntityList.size() != 100) {
                        break;
                    }
                }
            }

        }
        logger.info("flash chat 下发 END :" + new Date());
    }

    /**
     * 下发处理
     *
     * @param userFcConfigEntity
     * @param userEntity
     */
    private Integer dealCondition(UserFcConfigEntity userFcConfigEntity, UserEntity userEntity) {
        Integer dealResult = 0;
        //计算用户注册时间多久
        int minutes = (int) (((new Date()).getTime() - userEntity.getGmtCreate().getTime()) / 1000) / 60;
        if (minutes > userFcConfigEntity.getRegisterTime()) {
            //判断类型 读取用户 是否有 破冰会话 有效会话 深度会话  付费
            if (checkType(userFcConfigEntity.getTalkType(), userEntity.getUserCode())) {
                Map<String, Object> map = new HashMap<>();
                map.put("userCode", userEntity.getUserCode());
                Integer count = issueFcRecordDao.queryTotal(map);
                if (count < userFcConfigEntity.getFcCount()) {
                    if (userFcConfigEntity.getOverTime() > 0) {
                        //读取最新一条下发记录
                        IssueFcRecordEntity userFcEntity = issueFcRecordDao.getNewRecordByUserCode(userEntity.getUserCode());
                        if (userFcEntity != null) {
                            int overTime = (int) (((new Date()).getTime() - userFcEntity.getGmtCreate().getTime()) / 1000) / 60;
                            if (overTime >= userFcConfigEntity.getOverTime()) {
                                //下发
                                dealResult = sendMessage(userEntity.getUserCode());
                            }
                        } else {
                            //下发
                            dealResult = sendMessage(userEntity.getUserCode());
                        }
                    } else if (userFcConfigEntity.getFcCount() > 0) {
                        //下发
                        dealResult = sendMessage(userEntity.getUserCode());
                    }
                }
            }
        }
        return dealResult;
    }

    /**
     * 根据会话类型判断
     *
     * @param talkType
     * @param userCode
     * @return
     */
    private Boolean checkType(Integer talkType, String userCode) {
        boolean result = false;
        Map<String, Object> params = ServiceUtils.getParams();
        params.put("fromUserCode", userCode);

        //1破冰会话 2 有效会话 3 深度会话 4 付费
        switch (talkType) {
            case 1:
                params.put("limit", ConversationType.FIRST_CONVERSATION.getSize());
                return userMsgDao.getUserMsgByFromUserCode(params).isEmpty();
            case 2:
                params.put("limit", ConversationType.EFFECTIVE_CONVERSATIONS.getSize());
                return userMsgDao.getUserMsgByFromUserCode(params).isEmpty();
            case 3:
                params.put("limit", ConversationType.DEEP_CONVERSATIONS.getSize());
                return userMsgDao.getUserMsgByFromUserCode(params).isEmpty();
            case 4:
                List<TOrderDto> tOrderDtoList = new ArrayList<>();
                Response<List<TOrderDto>> response = tOrderService.queryOrder(userCode);
                if (response.isSuccess()) {
                    List<TOrderDto> tOrders = response.getData();
                    if (tOrders != null) {
                        tOrderDtoList = tOrders.stream().filter(o -> Objects.equals(2, o.getStatus())).collect(Collectors.toList());
                    }
                }
                return tOrderDtoList.isEmpty();
            default:
                return result;
        }
    }

    /**
     * 查询目标用户池 并下发
     *
     * @param userCode
     */
    private Integer sendMessage(String userCode) {
        // 0失败 1成功 2无推荐用户
        int sendMessageResult = 0;
        String friendUserCode = "";
        //查询用户池
        Response<List<RecommendUserDto>> response = wlmService.fcRecommendUsers(userCode, 1);
        if (response.isSuccess()) {
            List<RecommendUserDto> recommendUserDtoList = response.getData();
            if (recommendUserDtoList != null) {
                friendUserCode = recommendUserDtoList.get(0).getFriendUserCode();
                //下发
                final String sendMsgs = getCommonGreeting();
                if (StringUtils.isEmpty(sendMsgs)) {
                    addCommonLog(userCode, sendMessageResult, friendUserCode, "无问候语");
                    return sendMessageResult;
                }

                final JSONObject params = new JSONObject();
                params.put("toUserCode", userCode);
                params.put("fromUserCode", friendUserCode);
                params.put("content", sendMsgs);
                params.put("source", "flashChatIssueTask");


                final HashMap<String, String> header = Maps.newHashMap();
                header.put("accept", "application/json");
                header.put("content-type", "application/json");
                final String result = HttpUtil.postPageBody(sendFlashchatUrl, header, params.toJSONString());
                if (StringUtils.isEmpty(result)) {
                    logger.error("===SendFlashChatMsgTask, fromUserCode:{}, toUserCode:{},times:{}, reusltIsNull", userCode, friendUserCode, new Date());
                    addCommonLog(userCode, sendMessageResult, friendUserCode, "下发失败");
                    return sendMessageResult;
                }
                final JSONObject resultJson = JSONObject.parseObject(result);
                final int code = resultJson.getIntValue("code");
                if (code != 0) {
                    logger.error("===SendFlashChatMsgTask, fromUserCode:{}, toUserCode:{},times:{}, reuslt:{}", userCode, friendUserCode, new Date(), result);
                    addCommonLog(userCode, sendMessageResult, friendUserCode, "下发失败");
                    return sendMessageResult;
                }
                //发送通知
                if (otherService.pushNotification(userCode, 1).isSuccess()) {
                    //建联
                    AddWlmReq addWlmReq = new AddWlmReq();
                    addWlmReq.setUserCode(friendUserCode);
                    addWlmReq.setUserCodeFriend(userCode);
                    try {
                        wlmService.timeFlashChat(addWlmReq);
                    } catch (Exception e) {
                        logger.info("flash chat timeFlashChat 下发 userCode:{},friendUserCode:{},error:{}", userCode, friendUserCode, e.getMessage());
                    }

                    // 增加会话关系
                    final ConversationReq conversationReq = ConversationReq.builder().fromUserCode(friendUserCode).toUserCode(userCode)
                            .type(1).source(AppEnum.MECHAT.getAppCode()).latestTime(new Date()).latestMsg(sendMsgs).conversationType(1).build();
                    chatService.storageConversation(conversationReq);

                    pushMessage(friendUserCode, userCode, "S20005");
                    logger.info("flash chat 下发 userCode:{},friendUserCode:{}", userCode, friendUserCode);
                    //添加flash chat 记录
                    sendMessageResult = addUserFc(userCode, friendUserCode) ? 1 : 0;
                    //消息通知
                    Map<String, Object> map = new HashMap<>();
                    map.put("userCode", userCode);
                    Integer count = issueFcRecordDao.queryTotal(map);
                    if (count == 1) {
                        String message = "Flash chat⚡\uFE0F     \n" +
                                "When you are hit by a flash chat, don't wait, click on the dialog box to contact ta immediately!";
                        final UserEntity userEntity = userDao.selectByUserCode(userCode);
                        asyncSendMsgService.sendMsg(userEntity.getAppCode(), userCode, "RC:InfoNtf", message, message);
                    }
                }
            } else {
                sendMessageResult = 2;
            }
        }
        addCommonLog(userCode, sendMessageResult, friendUserCode, "");
        return sendMessageResult;
    }

    /**
     * 添加下发记录
     *
     * @param UserCode
     * @param userCodeFc
     * @return
     */
    private Boolean addUserFc(String UserCode, String userCodeFc) {
        IssueFcRecordEntity issueFcRecordEntity = new IssueFcRecordEntity();
        issueFcRecordEntity.setUserCode(UserCode);
        issueFcRecordEntity.setModelUserCode(userCodeFc);
        UserEntity userEntity= userDao.selectByUserCode(userCodeFc);
        issueFcRecordEntity.setOnlineStatus(userEntity.getOnline());
        IssueFcRecordEntity entity = issueFcRecordDao.insert(issueFcRecordEntity);
        return entity.getId() > 0;
    }

    /**
     * @return
     */
    private String getCommonGreeting() {
        final HashMap<String, Object> params = Maps.newHashMap();
        params.put("deleted", 0);
        params.put("greetingCode", 121);
        final List<UserGreetingCommonContentEntity> userGreetingCommonContentEntities = userGreetingCommonContentDao.selectByParams(params);
        if (CollectionUtils.isEmpty(userGreetingCommonContentEntities)) {
            return null;
        }
        Random random = new Random();
        int n = random.nextInt(userGreetingCommonContentEntities.size());
        return userGreetingCommonContentEntities.get(n).getGreetingContent();
    }


    private void pushMessage(String fromUseCode, String toUserCode, String target) {
        pushEventBus.post(buildEvent(fromUseCode, toUserCode, target));
    }

    private Event buildEvent(String fromUseCode, String toUserCode, String target) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("type", ParameterTypeEnum.PUSH_MODEL_ONLINE.getId());
        params.put("target", target);
        params.put("online", OnlineStatus.ONLINE_STATUS.getType());
        params.put("flashchatFlag", 1);
        return Event.builder().eventActionEnum(ActionEnum.PUSH_MSG).fromUserCode(fromUseCode).toUserCode(toUserCode).app(AppEnum.MEBOO).content(JSONObject.toJSONString(params)).build();
    }

    private void addCommonLog(String userCode, Integer result, String fromUseCode, String failReason) {
        StringBuilder content = new StringBuilder("flash chat:");
        content.append("userCode:");
        content.append(userCode);
        content.append(",");
        if (result == 0) {
            content.append("失败,");
            content.append(failReason);
        }
        if (result == 1) {
            content.append("fromUseCode:");
            content.append(fromUseCode);
            content.append(",成功");
        }
        if (result == 2) {
            content.append("失败,");
            content.append("目标用户池为空");
        }

        UserCommonLogEntity userCommonLogEntity = new UserCommonLogEntity();
        userCommonLogEntity.setCode("701");
        userCommonLogEntity.setUserCode(userCode);
        userCommonLogEntity.setContent(content.toString());
        commonLogDao.insert(userCommonLogEntity);

    }
}
